# -*- coding: utf-8 -*-

import json
import os
from pathlib import Path
from typing import Optional # Added import for Optional
from PySide2.QtCore import QObject, Signal, QCoreApplication
from PySide2.QtWidgets import QApplication

from gglobal import config
from gglobal import logger

class ThemeManager(QObject):
    """
    主题管理器，负责应用程序的主题切换功能。
    使用单例模式确保全局只有一个实例。
    """
    _instance = None
    _initialized = False
    
    theme_changed = Signal(str)  # 当主题改变时发出信号，参数为qss内容
    theme_constants_changed = Signal(dict) # 当主题常量改变时发出信号 (用于后续更改)
    initial_constants_loaded = Signal(dict) # 当初始主题常量加载时发出信号
    initial_qss_content_loaded = Signal(str) # 当初始QSS内容加载时发出信号

    def __new__(cls, qss_folder_path: str = None, parent=None):
        if cls._instance is None:
            cls._instance = super(ThemeManager, cls).__new__(cls)
        return cls._instance

    def __init__(self, qss_folder_path: str = None, parent=None):
        if self._initialized:
            return
        super(ThemeManager, self).__init__(parent)
        self.qss_folder_path = Path(qss_folder_path)
        self._themes = self._load_themes()
        self._current_theme_name = config.get_param("current_theme") or self.get_default_theme()
        logger.info(f"初始化主题管理器，QSS文件夹: {self.qss_folder_path}, 当前主题: {self._current_theme_name}")
        # 加载初始主题数据，但不立即应用
        self._load_initial_theme_data()
        
        # 标记为已初始化
        self._initialized = True

    def _load_themes(self) -> dict:
        """
        从指定文件夹加载所有主题文件（.qss 和 .json）。
        """
        themes = {}
        if not self.qss_folder_path.exists() or not self.qss_folder_path.is_dir():
            logger.error(f"QSS文件夹不存在或不是一个目录: {self.qss_folder_path}")
            return themes

        for file_path in self.qss_folder_path.iterdir():
            if file_path.suffix == ".qss":
                theme_name = file_path.stem
                json_path = self.qss_folder_path / f"{theme_name}.json"
                themes[theme_name] = {
                    "qss_path": file_path,
                    "json_path": json_path if json_path.exists() else None
                }
        logger.info(f"加载的主题: {list(themes.keys())}")
        return themes

    def _load_initial_theme_data(self):
        """加载初始主题的QSS和常量，并通过特定信号发出。"""
        if not self._current_theme_name or self._current_theme_name not in self._themes:
            logger.warning(f"初始主题 '{self._current_theme_name}' 未找到或无效。无法加载初始数据。")
            self.initial_constants_loaded.emit({}) # 发送空常量
            self.initial_qss_content_loaded.emit("")   # 发送空QSS
            return

        theme_data = self._themes[self._current_theme_name]
        qss_path = theme_data["qss_path"]
        json_path = theme_data["json_path"]

        # 首先加载并发送常量
        constants = {}
        if json_path and json_path.exists():
            try:
                with open(json_path, 'r', encoding='utf-8') as f:
                    constants = json.load(f)
                logger.info(f"为初始主题 '{self._current_theme_name}' 加载了JSON常量: {json_path.name}")
            except Exception as e:
                logger.error(f"为初始主题 '{self._current_theme_name}' 加载JSON常量失败 ({json_path.name}): {e}")
        else:
            logger.info(f"初始主题 '{self._current_theme_name}' 没有关联的JSON常量文件或文件未找到。")
        # self.initial_constants_loaded.emit(constants) # 信号已移除

        # 然后加载并记录QSS内容 (不再发射信号)
        qss_content = ""
        if qss_path.exists():
            try:
                with open(qss_path, 'r', encoding='utf-8') as f:
                    qss_content = f.read() # 读取内容，但不发射信号
                logger.info(f"为初始主题 '{self._current_theme_name}' 加载了QSS内容: {qss_path.name}")
            except Exception as e:
                logger.error(f"为初始主题 '{self._current_theme_name}' 加载QSS文件失败 ({qss_path.name}): {e}")
        else:
            logger.warning(f"初始主题 '{self._current_theme_name}' 的QSS文件未找到: {qss_path}")
        # self.initial_qss_content_loaded.emit(qss_content) # 信号已移除

    def get_initial_theme_data(self) -> dict:
        """直接获取初始主题的QSS和常量。"""
        if not self._current_theme_name or self._current_theme_name not in self._themes:
            logger.warning(f"初始主题 '{self._current_theme_name}' 未找到或无效。无法获取初始数据。")
            return {"constants": {}, "qss_content": ""}

        theme_data = self._themes[self._current_theme_name]
        qss_path = theme_data["qss_path"]
        json_path = theme_data["json_path"]

        constants = {}
        if json_path and json_path.exists():
            try:
                with open(json_path, 'r', encoding='utf-8') as f:
                    constants = json.load(f)
            except Exception as e:
                logger.error(f"为初始主题 '{self._current_theme_name}' 加载JSON常量失败 ({json_path.name}): {e}")
        
        qss_content = ""
        if qss_path.exists():
            try:
                with open(qss_path, 'r', encoding='utf-8') as f:
                    qss_content = f.read()
            except Exception as e:
                logger.error(f"为初始主题 '{self._current_theme_name}' 加载QSS文件失败 ({qss_path.name}): {e}")
        
        return {"constants": constants, "qss_content": qss_content}

    def get_available_themes(self) -> list:
        """
        获取所有可用的主题名称。
        """
        return list(self._themes.keys())

    def get_default_theme(self) -> str:
        """
        获取默认主题名称 (例如 'light' 或者列表中的第一个)。
        """
        if 'light' in self._themes:
            return 'light'
        elif self._themes:
            return list(self._themes.keys())[0]
        return ""

    def get_current_theme_name(self) -> str:
        """
        获取当前主题的名称。
        """
        return self._current_theme_name

    def apply_theme(self, theme_name: str):
        """
        应用指定的主题（主要用于主题切换）。
        """
        if theme_name not in self._themes:
            logger.warning(f"尝试应用不存在的主题: {theme_name}。将使用默认主题: {self.get_default_theme()}")
            theme_name = self.get_default_theme()
            if not theme_name:
                logger.error("没有可用的主题可以应用。")
                return

        theme_data = self._themes[theme_name]
        qss_path = theme_data["qss_path"]
        json_path = theme_data["json_path"]

        try:
            qss_content = ""
            if qss_path.exists():
                with open(qss_path, 'r', encoding='utf-8') as f:
                    qss_content = f.read()
                QApplication.instance().setStyleSheet(qss_content)
                self.theme_changed.emit(qss_content)
                logger.info(f"已应用主题QSS: {theme_name} (QSS: {qss_path.name})")
            else:
                logger.warning(f"应用主题时QSS文件未找到: {qss_path}")
                QApplication.instance().setStyleSheet("") # 清空样式
                self.theme_changed.emit("")

            constants = {}
            if json_path and json_path.exists():
                with open(json_path, 'r', encoding='utf-8') as f:
                    constants = json.load(f)
                logger.info(f"已加载主题常量: {theme_name} (JSON: {json_path.name})")
            else:
                logger.info(f"主题 '{theme_name}' 没有关联的JSON常量文件或文件未找到。")
            self.theme_constants_changed.emit(constants) # 总是发出，即使是空字典

            if self._current_theme_name != theme_name:
                 self._current_theme_name = theme_name
                 config.set_param("current_theme", self._current_theme_name)
                 logger.info(f"当前主题已更改为: {self._current_theme_name} 并已保存到配置。")

        except FileNotFoundError: # Should be caught by exists() checks, but as a fallback
            logger.error(f"主题文件读取时发生FileNotFoundError: {qss_path} 或 {json_path}")
        except json.JSONDecodeError:
            logger.error(f"解析主题常量JSON文件失败: {json_path}")
        except Exception as e:
            logger.error(f"应用主题时发生错误 ({theme_name}): {e}")



    def get_theme_constants(self, theme_name: Optional[str] = None) -> dict:
        """
        获取指定主题的常量。如果未指定主题名称，则返回当前主题的常量。
        """
        if theme_name is None:
            theme_name = self._current_theme_name
        
        if theme_name not in self._themes:
            logger.warning(f"获取常量时主题不存在: {theme_name}")
            return {}
            
        json_path = self._themes[theme_name].get("json_path")
        if json_path and json_path.exists():
            try:
                with open(json_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except Exception as e:
                logger.error(f"加载主题常量失败 ({theme_name}): {e}")
        return {}
    
    @classmethod
    def get_instance(cls, qss_folder_path: str = None, parent=None):
        """
        获取ThemeManager的单例实例
        
        参数:
            qss_folder_path: QSS文件夹路径，仅在首次创建时使用
            parent: 父对象，仅在首次创建时使用
        
        返回:
            ThemeManager: 单例实例
        """
        if cls._instance is None:
            cls._instance = cls(qss_folder_path, parent)
        return cls._instance

# 全局主题管理器实例 (如果需要的话)
# theme_manager = ThemeManager(qss_folder_path="path/to/your/qss/folder")